package com.faner.fast.util;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.domain.Page;

import java.util.*;

/**
 * 分页工具
 * description: PageUtil
 * date: 2020/11/24 14:21
 * author: faner
 */

@Data
public class PageUtil<T> extends cn.hutool.core.util.PageUtil {
    @ApiModelProperty(value = "总数")
    private Long total = 0L;

    private List<T> items  = new ArrayList<>();
    @ApiModelProperty(value = "页码")
    private Integer pageNum = 0;
    @ApiModelProperty(value = "每页数量")
    private Integer pageSize = 0;

    public PageUtil(){
        this.total = 0L;
        this.items = Collections.emptyList();
    }

    public PageUtil(IPage<T> page){
        this.items = page.getRecords();
        this.total = page.getTotal();
        this.pageNum = Math.toIntExact(page.getCurrent());
        this.pageSize = Math.toIntExact(page.getSize());
    }

    //List分页
    public  PageUtil(List<T> items,Integer page, Integer count) {
        int fromIndex = page * count;
        int toIndex = page * count + count;
        if(fromIndex > items.size()){
            this.items = new ArrayList<>();
        } else if(toIndex >= items.size()) {
            this.items = items.subList(fromIndex,items.size());
        } else {
            this.items = items.subList(fromIndex,toIndex);
        }
        this.pageNum = page;
        this.pageSize = count;
    }

    public PageUtil(Long total, List<T> items, Integer page, Integer count) {
        this.total = total;
        this.items = items;
        this.pageNum = page;
        this.pageSize = count;
    }

    /**
     * @param page IPage对象
     */
    public static <T> PageUtil resetPage(IPage<T> page)
    {
        return page == null ?
                new PageUtil(0L, Collections.emptyList(),Math.toIntExact(page.getCurrent()),Math.toIntExact(page.getSize()))
                :
                new PageUtil(page.getTotal(),page.getRecords(),Math.toIntExact(page.getCurrent()),Math.toIntExact(page.getSize()));
    }

    /**
     *  //List分页
     * @param items list集合
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @return map
     */
    public static Map<String, Object> toPage(List items,Integer pageNum, Integer pageSize) {
        Map<String,Object> res = new LinkedHashMap<>(4);
        int fromIndex = pageNum * pageSize;
        int toIndex = pageNum * pageSize + pageSize;
        if(fromIndex > items.size()){
            res.put("items",new ArrayList<>());
        } else if(toIndex >= items.size()) {
            res.put("items",items.subList(fromIndex,items.size()));
        } else {
            res.put("items",items.subList(fromIndex,toIndex));
        }
        res.put("total",items.size());
        res.put("pageNum", pageNum);
        res.put("pageSize", pageSize);
        return res;
    }

    /**
     *  List分页
     * @param items list分页条数
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @param count 总数
     * @return map
     */
    public static Map<String, Object> toPage(List items,Integer pageNum, Integer pageSize,Long count) {
        Map<String,Object> res = new LinkedHashMap<>(4);
        res.put("items",items);
        res.put("total",count);
        res.put("pageNum", pageNum);
        res.put("pageSize", pageSize);
        return res;
    }

    //-----------------------------------------以下方法自己调整----------------------------------------------------------------------

    /**
     * Page 数据处理，预防redis反序列化报错
     */
    public static Map<String,Object> toPage(Page page) {
        Map<String,Object> map = new LinkedHashMap<>(2);
        map.put("content",page.getContent());
        map.put("totalElements",page.getTotalElements());
        return map;
    }

    /**
     * 自定义分页
     */
    public static Map<String,Object> toPage(Object object, Object totalElements) {
        Map<String,Object> map = new LinkedHashMap<>(2);
        map.put("content",object);
        map.put("totalElements",totalElements);
        return map;
    }

}
